package task

import (
	"autoTestNew/pkg/commonType"
	_ "autoTestNew/pkg/commonType"
	"context"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	ctrl "sigs.k8s.io/controller-runtime"
)

var log = ctrl.Log.WithName("mongo/task")

// Validate 检查 Task 内容是否合法，返回错误和警告
/*func (t *commonType.Task) Validate() (err error, warnings []string) {
	// TODO 检查 Name 是否合法
	// TODO 检查 ApiDoc 是否合法
	// 检查 TraceTree 是否合法
	innerErr, innerWarnings := t.TraceTree.Validate()
	warnings = append(warnings, innerWarnings...)
	if innerErr != nil {
		err = innerErr
		return
	}
	// 检查 FaultConfig 是否合法
	for _, faultConfig := range t.FaultConfig {
		innerErr, innerWarnings = faultConfig.Validate()
		warnings = append(warnings, innerWarnings...)
		if innerErr != nil {
			err = innerErr
			return
		}
	}
	return
}*/

// Validate 检查 FaultConfig 内容是否合法，返回错误和警告
/*func (f *FaultConfig) Validate() (err error, warnings []string) {
	// TODO 检查 ServiceName 是否合法
	// 检查 FaultList 是否合法
	for _, fault := range f.FaultList {
		innerErr, innerWarnings := fault.Validate()
		warnings = append(warnings, innerWarnings...)
		if innerErr != nil {
			err = innerErr
			return
		}
	}
	return
}
*/
// Validate 检查 fault 内容是否合法，返回错误和警告
/*func (f *Fault) Validate() (err error, warnings []string) {
	// TODO 检查 ChaosType 是否合法
	// TODO 检查 Define 是否合法
	return
}
*/
// Validate 检查 TraceTree 内容是否合法，返回错误和警告
/*func (t *TraceTree) Validate() (err error, warnings []string) {
	// 检查 Nodes 是否合法
	for _, node := range t.Nodes {
		innerErr, innerWarnings := node.Validate()
		warnings = append(warnings, innerWarnings...)
		if innerErr != nil {
			err = innerErr
			return
		}
	}
	// 检查 Edges 是否合法
	for _, edge := range t.Edges {
		innerErr, innerWarnings := edge.Validate()
		warnings = append(warnings, innerWarnings...)
		if innerErr != nil {
			err = innerErr
			return
		}
	}
	return
}
*/
// Validate 检查 node 内容是否合法，返回错误和警告
/*func (n *Node) Validate() (err error, warnings []string) {
	// TODO 检查 ID 是否合法
	// TODO 检查 Name 是否合法
	// TODO 检查 TraceRequest 是否合法
	return
}
*/
// Validate 检查 edge 内容是否合法，返回错误和警告
/*func (e *Edge) Validate() (err error, warnings []string) {
	// TODO 检查 Source 是否合法
	// TODO 检查 Target 是否合法
	return
}
*/
// TODO 解析故障类型

type Store struct {
	collection *mongo.Collection
}

func NewStore(db *mongo.Database) *Store {
	return &Store{
		collection: db.Collection("task"),
	}
}

// Create 创建测试任务
func (s *Store) Create(ctx context.Context, task commonType.Task) (commonType.Task, error) {
	result, err := s.collection.InsertOne(ctx, task)
	if err != nil {
		log.Error(err, "insert task error", "task", task)
		return commonType.Task{}, err
	}
	objectID := result.InsertedID.(primitive.ObjectID)
	task.ID = &objectID
	return task, nil
}

// Get 获取测试任务
func (s *Store) Get(ctx context.Context, id primitive.ObjectID) (commonType.Task, error) {
	var task commonType.Task
	err := s.collection.FindOne(ctx, primitive.M{"_id": id}).Decode(&task)
	if err != nil {
		log.Error(err, "get task error", "id", id)
		return commonType.Task{}, err
	}
	return task, nil
}

// List 获取测试任务列表
func (s *Store) List(ctx context.Context) ([]commonType.Task, error) {
	var tasks []commonType.Task
	cursor, err := s.collection.Find(ctx, primitive.M{})
	if err != nil {
		log.Error(err, "list task error, find error")
		return nil, err
	}
	err = cursor.All(ctx, &tasks)
	if err != nil {
		log.Error(err, "list task error, decode error")
		return nil, err
	}
	return tasks, nil
}

// Update 更新测试任务
func (s *Store) Update(ctx context.Context, id primitive.ObjectID, task commonType.Task) error {
	_, err := s.collection.UpdateOne(ctx, primitive.M{"_id": id}, primitive.M{"$set": task})
	if err != nil {
		log.Error(err, "update task error", "id", id, "task", task)
		return err
	}
	return nil
}

// Delete 删除测试任务
func (s *Store) Delete(ctx context.Context, id primitive.ObjectID) error {
	_, err := s.collection.DeleteOne(ctx, primitive.M{"_id": id})
	if err != nil {
		log.Error(err, "delete task error", "id", id)
		return err
	}
	return nil
}

// DeleteAll 删除所有测试任务
func (s *Store) DeleteAll(ctx context.Context) error {
	_, err := s.collection.DeleteMany(ctx, primitive.M{})
	if err != nil {
		log.Error(err, "delete all task error")
		return err
	}
	return nil
}
